package lumis.service.portalmanagement.deployment;

import java.util.HashMap;
import java.util.Map;

import org.w3c.dom.Node;

import lumis.doui.control.ControlContainer;
import lumis.doui.control.IControl;
import lumis.doui.control.tabulardata.AdvancedTabularDataControl;
import lumis.doui.source.ISourceData;
import lumis.doui.source.TabularSource;
import lumis.portal.PortalException;
import lumis.portal.serviceinterface.IServiceInterfaceUrl;
import lumis.util.XmlUtil;

/**
 * Control to render a link to a runtime interface in a tabular data control.
 * The <code>runtimeInterfaceId</code> element specifies the id of the runtime
 * interface that must be called.
 * Also, it is possible to specify a set of parameters. For each parameter it
 * is possible to define the parameter name and the field id from which value
 * will be retrieved.
 * The attribute fieldId is required. The attribute name is optional. If it is
 * not specified, the parameter will be set with the same name of the field.
 * 
 * <p>
 * Example of a LinkToRuntimeTabularDataControl definition:
 * <xmp>
 * <runtimeInterfaceId>viewItem</runtimeInterfaceId>
 * <parameters>
 * 	<parameter name="itemId" fieldId="entryId" />
 * </parameters> 
 * </xmp>
 *
 * @version $Revision: 13092 $ $Date: 2011-05-28 18:19:06 -0300 (Sat, 28 May 2011) $
 * @since 6.0.0
 */
public class LinkToRuntimeTabularDataControl extends AdvancedTabularDataControl
{
	/**
	 * Runtime interface id element in control definition.
	 * @since 6.0.0
	 */
	private static String ELEMENT_RUNTIME_INTERFACE_ID = "runtimeInterfaceId";
	
	/**
	 * Parameter element query.
	 * @since 6.0.0
	 */	
	private static String ELEMENT_PARAMETER = "parameters/parameter";
	
	/**
	 * Parameter name attribute name.
	 * @since 6.0.0
	 */
	private static String ATTRIBUTE_NAME = "name";
	
	/**
	 * Field id attribute name.
	 * @since 6.0.0
	 */
	private static String ATTRIBUTE_FIELD_ID = "fieldId";
	
	/**
	 * The runtime interface id.
	 * @since 6.0.0
	 */
	private String runtimeInterfaceId;
	/**
	 * Parameters map where the key is the parameter name and the value is the
	 * field id to retrieve the parameter value.
	 * @since 6.0.0
	 */
	private Map<String, String> parameterMap = new HashMap<String, String>();
	/**
	 * Service id.
	 * @since 6.0.0
	 */	
	private String serviceId;
	/**
	 * Service instance id.
	 * @since 6.0.0
	 */	
	private String serviceInstanceId;

	
	@Override
	public void init(Node controlDefinitionNode,
					ControlContainer controlContainer,
					IControl parentControl)
				throws PortalException
	{
		super.init(controlDefinitionNode, controlContainer, parentControl);
		// reads the control definition
		readDefinition(controlDefinitionNode, controlContainer, parentControl);
	}

	/**
	 * Reads the control configuration and sets the control attributes.
	 * @param controlDefinitionNode		the definition node.
	 * @param controlContainer			the control container.
	 * @param parentControl				the parent control.
	 * @throws PortalException			if an error occur reading the definition.
	 * @since 6.0.0
	 */
	protected void readDefinition(Node controlDefinitionNode,
									ControlContainer controlContainer,
									IControl parentControl)
								throws PortalException
	{
		this.serviceId = douiContext.getRequest().getServiceConfig().getId();		
		this.serviceInstanceId = douiContext.getRequest().getServiceInstanceConfig().getId();
				
		Node nodeRuntimeInterface = XmlUtil.selectSingleNode(ELEMENT_RUNTIME_INTERFACE_ID, this.controlDefinitionNode);
		this.runtimeInterfaceId = XmlUtil.getTextContent(nodeRuntimeInterface);
				
		Node[] nodeList = XmlUtil.selectNodes(ELEMENT_PARAMETER, this.controlDefinitionNode);
		for (Node node: nodeList)
		{
			String fieldId = XmlUtil.readAttributeString(ATTRIBUTE_FIELD_ID, node);
			String parameterName = XmlUtil.readAttributeString(ATTRIBUTE_NAME, node);
			
			if ((parameterName == null) ||(parameterName.equals(""))) 
			{
				parameterName = fieldId;
			}
			
			this.parameterMap.put(parameterName, fieldId);
		}
	}	
	
	@Override
	protected String getFieldHyperlink(
						TabularSource source,
						ISourceData row,
						String fieldId,
						String compositePrimaryKey,
						int rowIndex)
				throws PortalException
	{
		String serviceInterfaceId = serviceId + "." + this.runtimeInterfaceId;
		
		if (fieldId.equals("numErrors"))
		{
			IServiceInterfaceUrl url = douiContext.getResponse().createRenderURL();
			url.setRunTimeServiceInstanceId(serviceInstanceId);
			url.setRunTimeServiceInterfaceId(serviceInterfaceId);

			for (String parameterName: this.parameterMap.keySet())
			{
				String field = this.parameterMap.get(parameterName);
				url.setParameter(parameterName, (String) row.get(field));
			}
			
			return url.toString();
		}
		else
		{
			return null;
		}
	}
	
	@Override
	protected String getRowHyperlink(
						TabularSource source,
						ISourceData row,
						String compositePrimaryKey,
						int rowIndex)
					throws PortalException
	{
		return null;
	}
}